# Filters added to this controller apply to all controllers in the application.
# Likewise, all the methods added will be available for all controllers.

class ApplicationController < ActionController::Base
  # Pick a unique cookie name to distinguish our session data from others'
  session :session_key => '_efficiency_session_id'
  def date_select_parse(object,name)
    begin
      Time.parse(Date.civil(params[object][name+"(1i)"].to_i,params[object][name+"(2i)"].to_i,params[object][name+"(3i)"].to_i).to_s)
    rescue
      false
    end
  end
  def kernel_open(command)
    cmd = open(command)
    value = cmd.gets
    cmd.close
    return value
  end
  private
    def login_required
      ids = [1,2]
      if !session[:user_id] or !ids.include?(session[:user_id])
        redirect_to :controller => :user, :action => :login and return
      end
    end
end
class BigDecimal
  def round_to(x)
    (self * 10**x).round.to_f / 10**x
  end
end
class Float
  def round_to(x)
    (self * 10**x).round.to_f / 10**x
  end
  def ceil_to(x)
    (self * 10**x).ceil.to_f / 10**x
  end
  def floor_to(x)
    (self * 10**x).floor.to_f / 10**x
  end
end
class Array
  def variance
    n = 0
    mean = 0.0
    s = 0.0
    self.each { |x|
      n = n + 1
      delta = x - mean
      mean = mean + (delta / n)
      s = s + delta * (x - mean)
    }
    return s / (n-1) unless n-1==0
    return 0
  end
  def std
    Math.sqrt(variance)
  end
  def sum
    inject(nil) { |sum,x| sum ? sum+x : x }
  end
  def mean
    return 0 if self.length==0
    sum / size 
  end
  def median
    self.sort
    length = self.length
    if length%2==0
      return self[length/2-1]
    else
      return self[(length-1)/2]
    end
  end
  def order(k)
    return 0 if self.length==0
    k = 1 if k<1
    k = self.length if k>self.length
    m = self.order_median
    l = self.select{|x| x<m}
    r = self.select{|x| x>m}
    diff = self.length-l.length-r.length
    if l.length+1<=k and k<=l.length+diff
      return m
    elsif k<=l.length
      return l.order(k)
    else
      return r.order(k-l.length-diff)
    end
  end
  def order_median
    return self.median if self.length<5
    medians = Array.new
    set = Array.new
    counter = 0
    n = 0
    for i in self
      n += 1
      counter += 1
      set << i
      if counter==5
        set = set.sort
        medians << set[2]
        counter = 0
        set = Array.new
      end
    end
    return medians.median
  end
  def remove_outliers
    mean = self.mean
    std = self.std
    reject{|x| (x-mean).abs/std>=1.35}
  end
  def summary
    length = self.length
    if length==0
      return {:min => 0.0, :q1 => 0.0, :med => 0.0, :q3 => 0.0, :max => 0.0, :avg => 0.0, :std => 0.0}
    end
    return {:min => self.min, :q1 => self.order((0.25*length).to_i), :med => self.order((0.5*length).to_i), :q3 => self.order((0.75*length).to_i), :max => self.max, :avg => self.mean, :std => self.std}
  end
end
